package top.cardone.data.listener;

import com.google.common.collect.Lists;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationListener;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.util.CollectionUtils;
import top.cardone.context.ApplicationContextHolder;
import top.cardone.context.event.SimpleEvent;
import top.cardone.core.util.action.Action0;
import top.cardone.core.util.action.Action1;
import top.cardone.data.action.SaveListByGenerateListenerAction;

import java.util.List;
import java.util.Map;

/**
 * @author yao hai tao
 * @date 2017/7/18
 */
@Log4j2
public class GenerateListener implements ApplicationListener<SimpleEvent> {
    @Setter
    private List<String> removeStrings = Lists.newArrayList(".impl", "Impl");

    @Setter
    private List<String> exclusionMethodName = Lists.newArrayList("read*", "find*", "page*", "generate*");

    @Setter
    private List<String> generateMethodName = Lists.newArrayList("save*Cache", "insert*Cache", "delete*Cache", "update*Cache", "execute*Cache");

    @Setter
    private String serviceBeanId;

    @Setter
    private List<Map<String, Object>> saveList;

    @Setter
    private String taskExecutorBeanName = "slowTaskExecutor";

    @Setter
    private List<String> actionBeanNames;

    @Override
    public void onApplicationEvent(SimpleEvent simpleEvent) {
        if (StringUtils.isBlank(serviceBeanId)) {
            return;
        }

        if (ArrayUtils.isEmpty(simpleEvent.getFlags())) {
            return;
        }

        if (top.cardone.context.util.StringUtils.matchs(exclusionMethodName, simpleEvent.getFlags()[1])) {
            return;
        }

        if (!top.cardone.context.util.StringUtils.matchs(generateMethodName, simpleEvent.getFlags()[1])) {
            return;
        }

        String eventServiceName = simpleEvent.getFlags()[0];

        for (String removeString : removeStrings) {
            eventServiceName = StringUtils.remove(eventServiceName, removeString);
        }

        if (!StringUtils.equals(serviceBeanId, eventServiceName)) {
            return;
        }

        ApplicationContextHolder.getBean(AsyncListenableTaskExecutor.class, this.taskExecutorBeanName).submitListenable(() -> {
            if (!CollectionUtils.isEmpty(saveList)) {
                try {
                    ApplicationContextHolder.getBean(SaveListByGenerateListenerAction.class).action(saveList);
                } catch (Exception e) {
                    log.error(e);
                }
            }

            if (!CollectionUtils.isEmpty(actionBeanNames)) {
                for (String actionBeanName : actionBeanNames) {
                    try {
                        Object action = ApplicationContextHolder.getBean(actionBeanName);

                        if (action == null) {
                            continue;
                        }

                        if (action instanceof Action0) {
                            ((Action0) action).action();
                        } else if (action instanceof Action1) {
                            ((Action1) action).action(simpleEvent);
                        }

                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        log.error(e);
                    }
                }
            }
        });
    }
}
